package exchange.direct;

import com.rabbitmq.client.*;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

/**
 * Created with IDEA
 * Author: LuoHengYi
 * Date: 2022/6/17
 * Time: 11:02
 */
public class ReceiverDirectExchange {
    public static void main(String[] args) {


        //创建链接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("127.0.0.1");
        connectionFactory.setPort(5672);
        //作用域，不同的业务可以分配不同的作用域 /order ，/message
        connectionFactory.setVirtualHost("/");

        //网络异常自动连接恢复
        connectionFactory.setAutomaticRecoveryEnabled(true);
        // 每3秒尝试重试连接一次
        connectionFactory.setNetworkRecoveryInterval(3000);


        Connection connection = null;
        try {
            //创建链接
            connection = connectionFactory.newConnection();

            //每个Channel代表一个会话任务,类似sqlsession
            Channel channel = connection.createChannel();

            //创建交换机，队列，并使用 routingKey 进行绑定
            //buildExchangeAndQueueAndQueueBind(channel);

            //创建一个消费者 // 消费者订阅消息 监听如上声明的队列
            DefaultConsumer defaultConsumer = new DefaultConsumer(channel){

                @Override
                public void handleRecoverOk(String consumerTag) {
                    super.handleRecoverOk(consumerTag);
                    System.out.println("----------->"+consumerTag);
                }

                @Override
                public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                    super.handleDelivery(consumerTag, envelope, properties, body);
                    System.out.println(consumerTag);
                    System.out.println(envelope.toString());
                    System.out.println(properties.toString());
                    System.out.println( "消息内容:" + new String(body));
                }
            };

            //队列名称
            String queueName="test_direct_query";

            //设置队列名称、消息自动ack(标记该消费成功)、消费者
            channel.basicConsume(queueName,false,defaultConsumer);


        } catch (IOException e) {
            e.printStackTrace();
        } catch (TimeoutException e) {
            e.printStackTrace();
        }


    }

    /**
     * 创建交换机，队列，并使用 routingKey 进行绑定
     * @param channel
     * @throws IOException
     */
    private static void buildExchangeAndQueueAndQueueBind(Channel channel) throws IOException {


        //交换机名称
        String exchangeName="test_direct_exchange";
        //交换机类型
        String exchangeType="direct";
        //队列名称
        String queueName="test_direct_query";
        //routingKey 路由规则
        String routingKey="test_direct_routingKey";


        /*
         * 创建交换机
         *  exchange 交换机名称
         *  type 交换机类型
         *  durable 是否持久化，没有持久化的交换机，否则重启后就没有了
         *  autoDelete 交换机没有使用时自动删除
         *  internal
         *  arguments 交换的其他属性（构造参数）
         */
        channel.exchangeDeclare(exchangeName,exchangeType,true,false,false,null);

        /* 创建队列
         * queue 队列名称
         * durable 是否持久队列， （该队列将在服务器重新启动后继续存在）
         * exclusive 独占的queue（该队列只能有一个链接）
         * autoDelete 队列没有使用时自动删除
         * arguments  队列的其他属性（构造参数）
         */
        channel.queueDeclare(queueName,false,false,false,null);


        // 使用 routingKey 将 队列 和 交换机 绑定
        channel.queueBind(queueName,exchangeName,routingKey);



    }
}
